package com.sdp.th.db.th_eq_alarm_trend_log.service.impl;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sdp.th.cache.caches.AlarmSetCache;
import com.sdp.th.db.th_alarm_count.service.IThAlarmCountService;
import com.sdp.th.db.th_eq_alarm_trend_log.mapper.ThEqAlarmTrendLogMapper;
import com.sdp.th.db.th_eq_alarm_trend_log.service.IThEqAlarmTrendLogService;
import com.sdp.th.db.th_eq_info.service.IThEqInfoService;
import com.sdp.th.db.th_eq_state_log.service.IThEqStateLogService;
import com.sdp.th.entity.ThEqAlarmSet;
import com.sdp.th.entity.ThEqAlarmTrendLog;
import com.sdp.th.entity.ThEqInfo;
import com.sdp.th.entity.ThEqState;
import com.sdp.th.entity.ThEqStateLog;
import com.sdp.th.utils.ThConstants;

/**
 * <p>
 * 设备趋势报警日志 服务实现类
 * </p>
 *
 * @author zsp
 * @since 2025-04-16
 */
@Service
public class ThEqAlarmTrendLogServiceImpl extends ServiceImpl<ThEqAlarmTrendLogMapper, ThEqAlarmTrendLog> implements IThEqAlarmTrendLogService {

	@Autowired
	private IThEqInfoService iThEqInfoService;
	
	@Autowired
	private IThEqStateLogService iThEqStateLogService;
	
	@Autowired
	private IThAlarmCountService iThAlarmCountService;
	
	@Autowired
	private AlarmSetCache alarmSetCache;
	
	@Override
	@Transactional(rollbackFor=Exception.class)
	public boolean verifyTrendAlarm(ThEqState thEqState) {
		if(thEqState==null || StringUtils.isEmpty(thEqState.getDeviceNo())) {
			return false;
		}
		
		ThEqAlarmSet alarmSet = alarmSetCache.getAlarmSetCacheByNo(thEqState.getDeviceNo());
	
		if(alarmSet==null) {
			return false;
		}
		
		if(alarmSet.getHumidityTrendTime()==null && alarmSet.getHumidityTrendVal()==null
				&& alarmSet.getTemperatureTrendTime()==null && alarmSet.getTemperatureTrendVal()==null) {
			return false;
		}
		
		//查询设备基础信息
		ThEqInfo eqInfo = iThEqInfoService.queryEqInfoByNo(thEqState.getDeviceNo());
		
		List<ThEqAlarmTrendLog> logList = new ArrayList<>();
		
		//处理温度趋势
		verifyTemperatureTrend(alarmSet, thEqState, eqInfo, logList);
		
		//处理湿度趋势
		verifyHumidityTrend(alarmSet, thEqState, eqInfo, logList);
		
		if(logList.size()>0) {
			saveBatch(logList);
			
			//统计趋势报警次数
			iThAlarmCountService.setAlarmTrendCount(BigDecimal.valueOf(logList.size()));
		}
		
		return false;
	}
	
	
	private void verifyHumidityTrend(ThEqAlarmSet alarmSet,ThEqState thEqState, ThEqInfo eqInfo,List<ThEqAlarmTrendLog> logList) {
		if(alarmSet.getHumidityTrendTime()==null || alarmSet.getHumidityTrendVal()==null) {
			return ;
		}
		//最后数据增加1秒，为了数据能查的全
		LocalDateTime now = LocalDateTime.now();
		LocalDateTime et = now.plusSeconds(1);
		
		BigDecimal hours = alarmSet.getHumidityTrendTime();
		BigDecimal trendVal = alarmSet.getHumidityTrendVal();
		
		 // 计算小时数对应的Duration
        Duration duration = Duration.ofHours(Long.parseLong(hours+""));
        
        // 从当前时间减去这个Duration，得到之前的时间
        LocalDateTime st = now.minus(duration).plusSeconds(-1);
		
		List<ThEqStateLog> stateLog = iThEqStateLogService.queryStateLogByEqAndDate(thEqState.getDeviceNo(), st,et);
		
		if(stateLog==null || stateLog.size()==0) {
			return;
		}
		
		if(isTrendAlarm(trendVal, stateLog,ThConstants.报警类型_湿度.getCode())) {
			//生成日志
			ThEqAlarmTrendLog alarmLog = new ThEqAlarmTrendLog();
			alarmLog.setDeviceNo(thEqState.getDeviceNo());
			alarmLog.setCreateTime(LocalDateTime.now());
			alarmLog.setAlarmAction(ThConstants.报警处理_未处理.getCode());
			alarmLog.setAlarmType(ThConstants.报警类型_湿度.getCode());
			
			if(eqInfo!=null) {
				alarmLog.setDeviceRoom(eqInfo.getDeviceRoom());
				alarmLog.setDeviceRegion(eqInfo.getDeviceRegion());
				alarmLog.setDeviceName(eqInfo.getDeviceName());
			}
			
			alarmLog.setTrendSt(st);
			alarmLog.setTrendEt(et);
			
			logList.add(alarmLog);
		}
		
	}
	
	
	
	private void verifyTemperatureTrend(ThEqAlarmSet alarmSet,ThEqState thEqState, ThEqInfo eqInfo,List<ThEqAlarmTrendLog> logList) {
		if(alarmSet.getTemperatureTrendTime()==null || alarmSet.getTemperatureTrendVal()==null) {
			return ;
		}
		LocalDateTime now = LocalDateTime.now();
		
		BigDecimal hours = alarmSet.getTemperatureTrendTime();
		BigDecimal trendVal = alarmSet.getTemperatureTrendVal();
		
		 // 计算小时数对应的Duration
        Duration duration = Duration.ofHours(Long.parseLong(hours+""));
        
        // 从当前时间减去这个Duration，得到之前的时间
        LocalDateTime st = now.minus(duration);
		
		List<ThEqStateLog> stateLog = iThEqStateLogService.queryStateLogByEqAndDate(thEqState.getDeviceNo(), st,now);
		
		if(stateLog==null || stateLog.size()==0) {
			return;
		}
		
		if(isTrendAlarm(trendVal, stateLog,ThConstants.报警类型_温度.getCode())) {
			//生成日志
			ThEqAlarmTrendLog alarmLog = new ThEqAlarmTrendLog();
			alarmLog.setDeviceNo(thEqState.getDeviceNo());
			alarmLog.setCreateTime(LocalDateTime.now());
			alarmLog.setAlarmAction(ThConstants.报警处理_未处理.getCode());
			alarmLog.setAlarmType(ThConstants.报警类型_温度.getCode());
			alarmLog.setTrendSt(st);
			alarmLog.setTrendEt(now);
			if(eqInfo!=null) {
				alarmLog.setDeviceRoom(eqInfo.getDeviceRoom());
				alarmLog.setDeviceRegion(eqInfo.getDeviceRegion());
				alarmLog.setDeviceName(eqInfo.getDeviceName());
			}
		
			logList.add(alarmLog);
		}
		
	}
	
	
	/**
	 * 监测是否需要趋势报警
	 * @return
	 */
	private boolean isTrendAlarm(BigDecimal trendVal,List<ThEqStateLog> stateLog,String alarmType) {
		 // 初始化最大值和最小值为第一个元素
        BigDecimal max = BigDecimal.ZERO;
        BigDecimal min = BigDecimal.ZERO;
        BigDecimal num = BigDecimal.ZERO;
        if(ThConstants.报警类型_温度.getCode().equals(alarmType)) {
        	max = stateLog.get(0).getDeviceTemperature();
        	min = stateLog.get(0).getDeviceTemperature();
        }else {
        	max = stateLog.get(0).getDeviceHumidity();
        	min = stateLog.get(0).getDeviceHumidity();
        }
        // 遍历集合更新最大值和最小值
        for(ThEqStateLog state : stateLog) {
        	if(ThConstants.报警类型_温度.getCode().equals(alarmType)) {
        		num = state.getDeviceTemperature();
        	}else {
        		num = state.getDeviceHumidity();
        	}
        	if (num.compareTo(max) > 0) {
                max = num;
            }
            if (num.compareTo(min) < 0) {
                min = num;
            }
        }
        // 计算极差值并与阈值比较
        BigDecimal difference = max.subtract(min);
        return difference.compareTo(trendVal) > 0;
        
	}


	@Override
	public int needHandleAlarmCount() {
		LambdaQueryWrapper<ThEqAlarmTrendLog> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(ThEqAlarmTrendLog::getAlarmAction, ThConstants.报警处理_未处理.getCode());
		return count(queryWrapper);
	}
}
